﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NAudio.Wave;

namespace Mic
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            this.FormBorderStyle = FormBorderStyle.None;
            this.Icon = Properties.Resources.bofang_256x256;
            this.MouseDown += Form1_MouseDown;
            RoView();
            base.SetStyle(
                ControlStyles.UserPaint |
                ControlStyles.DoubleBuffer |
                ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.ResizeRedraw |
                ControlStyles.SupportsTransparentBackColor, true);
            base.UpdateStyles();
            this.BackColor = Color.Transparent;
            this.Font = new Font("微软雅黑", 15);
            list.AddRange(Directory.GetFiles("d:\\mp3", "*.mp3"));
            list.AddRange(Directory.GetFiles("d:\\mp3", "*.m4a"));
            this.Image = Properties.Resources._0;
            this.Size = new Size(60, 80);

            this.StartPosition = FormStartPosition.Manual;
            this.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - this.Width - 20, 20);
            this.TopMost = true;
            this.Shown += Form1_Shown;

            //拖拽文件
            this.AllowDrop = true;
            this.DragDrop += Form1_DragDrop;
            this.DragEnter += Form1_DragEnter;

            menuStrip = new ContextMenuStrip();

            var toolStripMenuItem1 = new ToolStripMenuItem("退出");
            var toolStripMenuItem2 = new ToolStripMenuItem("上一曲");
            var toolStripMenuItem3 = new ToolStripMenuItem("下一曲");
            var toolStripMenuItem4 = new ToolStripMenuItem("暂停");
            var toolStripMenuItem5 = new ToolStripMenuItem("单曲循环");
            var toolStripMenuItem6 = new ToolStripMenuItem("随机播放");

            toolStripMenuItem1.Click += ToolStripMenuItem1_Click;
            toolStripMenuItem2.Click += ToolStripMenuItem2_Click;
            toolStripMenuItem3.Click += ToolStripMenuItem3_Click;
            toolStripMenuItem4.Click += ToolStripMenuItem4_Click;
            toolStripMenuItem5.Click += ToolStripMenuItem5_Click;
            toolStripMenuItem6.Click += ToolStripMenuItem6_Click;

            menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem1, toolStripMenuItem2, toolStripMenuItem3, toolStripMenuItem4, toolStripMenuItem5, toolStripMenuItem6 });

            this.ContextMenuStrip = menuStrip;

            GraphicsPath path = new GraphicsPath();
            path.AddRectangle(new RectangleF(0, size.Height, size.Width, 20));
            path.AddEllipse(0, 0, size.Width, size.Height);

            this.Region = new Region(path);
        }

        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            string path = ((Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();       //获得路径
            if (Path.GetExtension(path) == ".mp3")
            {
                Start(path);
            }
        }

        private void Form1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.All;
            //重要代码：表明是所有类型的数据，比如文件路径
            else
                e.Effect = DragDropEffects.None;
        }

        #region 背景颜色镂空
        private const uint WS_EX_LAYERED = 0x80000;//异形窗体特效的实现
        private const int GWL_EXSTYLE = -20;//设定一个新的扩展风格
        private const int LWA_COLORKEY = 1;//透明方式
        [DllImport("user32", EntryPoint = "SetWindowLong")]
        //改变指定窗口的属性
        private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);
        [DllImport("user32", EntryPoint = "SetLayeredWindowAttributes")]
        //设置分层窗口透明度
        private static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, int bAlpha, int dwFlags);

        private void Form1_Shown(object sender, EventArgs e)
        {
            BackColor = Color.FromArgb(58, 58, 58);
            TransparencyKey = Color.FromArgb(58,58,58);
            Next();
        }
        #endregion

        #region 私有属性
        private Color TimeColor = Color.FromArgb(61,61,61);
        //画布旋转角度
        private int ro = 0;
        private readonly StringFormat sf = new StringFormat(StringFormatFlags.NoWrap | StringFormatFlags.NoClip) { LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center };

        private ContextMenuStrip menuStrip;
        private string LastPath { get; set; }
        private string NowPlaying { get; set; }
        private bool one = false;
        #endregion

        #region 定时旋转角度

        private void RoView()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    Task.Delay(200).Wait();
                    if (!StartRo) continue;
                    ro += 10;
                    if (ro >= 360)
                        ro = 0;
                    this.Invalidate();
                }
            });
        }
        private bool StartRo = false;

        #endregion

        List<string> list = new List<string>();

        #region 播放音乐
        private IWavePlayer player;
        private AudioFileReader reader;
        private void Start(string path)
        {
            NowPlaying = path;
            var imgurl = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path) + ".jpg");
            if (File.Exists(imgurl))
                this.Image = new Bitmap(imgurl);
            else
                this.Image = Properties.Resources._0;
            this.Text = "正在播放 " + Path.GetFileNameWithoutExtension(path) + " - 森云科技";
            DisposeAll();
            Task.Run(() =>
            {
                try
                {
                    reader = new AudioFileReader(path);
                    player = new WaveOutEvent();
                    player.Init(reader);
                    player.Play(); //异步执行
                    player.PlaybackStopped += Player_PlaybackStopped;
                }
                catch { this.Invoke(new Action(Next)); }
            });
        }

        private void Player_PlaybackStopped(object sender, StoppedEventArgs e)
        {
            this.Invoke(new Action(Next));
        }

        private void Next()
        {
            if (one && NowPlaying != null)
            {
                StartRo = true;
                Start(NowPlaying);
                return;
            }

            if (NowPlaying != null)
                LastPath = NowPlaying;
            StartRo = true;
            Start(list[new Random().Next(list.Count - 1)]);
        }

        private void LastMic()
        {
            if (LastPath == null)
                return;
            StartRo = true;
            Start(LastPath);
        }

        private void Pause()
        {
            StartRo = false;
            player?.Pause();
        }

        #endregion

        private void DisposeDevice()
        {
            if (player != null)
            {
                player.PlaybackStopped -= Player_PlaybackStopped;
                player.Dispose();
            }
        }

        private void DisposeAll()
        {
            reader?.Dispose();
            DisposeDevice();
            player = null;
            reader = null;
        }
        public Image Image { get; set; }
        private Size size { get; set; } = new Size(60, 60);
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;

            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            //播放时间
            var dest = new RectangleF(size.Width / 2, size.Height / 2, size.Width, size.Height);
            var con = g.BeginContainer(dest, new RectangleF(0, 0, size.Width, size.Height), GraphicsUnit.Pixel);

            GraphicsPath gp = new GraphicsPath();
            gp.AddEllipse(-size.Width / 2, -size.Height / 2, size.Width, size.Height);
            g.RotateTransform(ro);
            g.SetClip(gp);
            g.DrawImage(Image, -size.Width / 2, -size.Height / 2, size.Width, size.Height);
            g.EndContainer(con);
            try
            {
                if (reader != null && (reader?.TotalTime ?? new TimeSpan(0)) - (reader?.CurrentTime ?? new TimeSpan(0)) is TimeSpan t)
                    g.DrawString(t.Minutes + ":" + t.Seconds.ToString("00"), this.Font, new SolidBrush(TimeColor), new RectangleF(0, 60, size.Width, 20), sf);
            }
            catch { }
        }

        #region 无边框拖动效果
        [DllImport("user32.dll")]//拖动无窗体的控件
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        public const int WM_SYSCOMMAND = 0x0112;
        public const int SC_MOVE = 0xF010;
        public const int HTCAPTION = 0x0002;

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Clicks >= 2)
            {
                if (e.Button == MouseButtons.Left)
                {
                    Next();
                }
            }

            if (e.Button == MouseButtons.Middle)
            {
                StartRo = !StartRo;
                if (StartRo)
                {
                    if (player is null)
                        Next();
                    else
                        player.Play();
                }
                else
                    player?.Pause();
            }

            if (e.Button == MouseButtons.Left && e.Clicks == 1)
            {
                //拖动窗体
                ReleaseCapture();
                SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
            }
        }

        #endregion

        private void ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void ToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            LastMic();
        }

        private void ToolStripMenuItem3_Click(object sender, EventArgs e)
        {
            Next();
        }

        private void ToolStripMenuItem4_Click(object sender, EventArgs e)
        {
            Pause();
        }

        private void ToolStripMenuItem5_Click(object sender, EventArgs e)
        {
            one = true;
        }
        private void ToolStripMenuItem6_Click(object sender, EventArgs e)
        {
            one = false;
        }
    }
}
